import {
  Injectable,
  NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { PrismaService } from '../prisma/prisma.service';
import { updateAccountDto } from './dto/update-account.dto';
import * as bcrypt from 'bcrypt';

@Injectable()
export class UsersService {
  constructor(private prisma: PrismaService) {}

  async findOne(id: number) {
    const user = await this.prisma.user.findUnique({
      where: {
        id: id,
      },
      include: {
        familys: true,
      },
    });
    if (user) {
      const { password, ...result } = user;
      return result;
    }
    return user;
  }

  update(id: number, updateUserDto: UpdateUserDto) {
    return this.prisma.user.update({
      where: {
        id: id,
      },
      data: { ...updateUserDto, birthday: new Date(updateUserDto.birthday) },
    });
  }

  async accountSet(id: number, updateAccountDto: updateAccountDto) {
    return this.prisma.$transaction(async (prisma) => {
      const user = await prisma.user.findUnique({
        where: { id },
        select: {
          id: true,
          password: true,
          account: true,
        },
      });

      if (!user) {
        throw new NotFoundException({ code: 4041, message: '用户不存在' });
      }

      const updateData: Partial<updateAccountDto> = {};

      if (updateAccountDto.oldPassword) {
        const isPasswordValid = await bcrypt.compare(
          updateAccountDto.oldPassword,
          user.password,
        );

        if (!isPasswordValid) {
          throw new BadRequestException({ code: 4001, message: '旧密码错误' });
        }

        if (updateAccountDto.newPassword) {
          updateData.password = await bcrypt.hash(
            updateAccountDto.newPassword,
            10,
          );
        }
      }

      if (
        updateAccountDto.account &&
        updateAccountDto.account !== user.account
      ) {
        updateData.account = updateAccountDto.account;
      }

      if (Object.keys(updateData).length === 0) {
        return user;
      }

      try {
        return await prisma.user.update({
          where: { id },
          data: updateData,
          select: {
            account: true
          },
        });
      } catch (error) {
        if (
          error.code === 'P2002' && 
          (error.meta?.target?.includes('account') || error.meta?.target?.includes('user_account_key'))
        ) {
          throw new BadRequestException({ code: 4002, message: '此账号已存在' });
        }
        console.error('Unexpected error:', error);
        throw error;
      }
    });
  }
}
